package nk;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import arq.arq;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.sparql.core.TriplePath;
import com.hp.hpl.jena.sparql.syntax.Element;
import com.hp.hpl.jena.sparql.syntax.ElementGroup;
import com.hp.hpl.jena.sparql.syntax.ElementOptional;
import com.hp.hpl.jena.sparql.syntax.ElementPathBlock;
import com.hp.hpl.jena.sparql.syntax.ElementSubQuery;
import com.hp.hpl.jena.sparql.syntax.ElementUnion;
import com.hp.hpl.jena.sparql.syntax.ElementVisitorBase;
import com.hp.hpl.jena.sparql.syntax.ElementWalker;

public class Teste {

	public static Map<Integer, Object> map = new HashMap();
	static int count = 0;
	int nivel = 0;
	boolean root = false;
	boolean bpg = false;

	public static Map<Integer, Object> getMap() {
		return map;
	}

	public static void setMap(Map<Integer, Object> map) {
		Teste.map = map;
	}

	public static int getCount() {
		return count;
	}

	public static void setCount(int count) {
		Teste.count = count;
	}

	Arvore arvore = new Arvore();

	public void addMap(Object obj) {
		count = count + 1;
		map.put(count, obj);
	}

	/**
	 * Calcula a profundidade do grafo OBS: Este tem somente ate o nivel 3
	 * aumentar o nivel caso necessario
	 * 
	 * @param nivel
	 * @param obj
	 */
	public void calculaNivel(int nivel, Object obj) {
		if (nivel == 0) {
			arvore.cria(obj, arvore.root());
		} else if (nivel == 1) {
			arvore.cria(obj, arvore.irmao(arvore.filho(arvore.root())));
		} else if (nivel == 2) {
			arvore.cria(obj, arvore.filho(arvore.filho(arvore.root())));
		} else {
			arvore.cria(obj, arvore.filho(arvore.filho(arvore.filho(arvore.root()))));
		}
	}

	/**
	 * insere cada elemento em sua posicao
	 * 
	 * @param vetor
	 */
	public void organizaVetor(Map<Integer, Object> vetor) {
		arvore.cria("");
		for (Object objeto : vetor.values()) {
			if ((objeto.equals("UNION") || objeto.equals("OPT")) && !root) {
				arvore.cria(objeto);
				root = true;
				nivel++;
			} else {
				if ((objeto.equals("UNION") || objeto.equals("OPT"))) {
					nivel++;
				}
				calculaNivel(nivel, objeto);
//				arvore.cria(objeto, arvore.root());
			}

		}
	}

	public static void main(String[] args) {

		final Teste teste = new Teste();

		String query = "PREFIX foaf: <http://xmlns.com/foaf/0.1/>"
				+ " PREFIX vCard: <http://www.w3.org/2001/vcard-rdf/3.0#>"
				+ " SELECT ?name"
				+ " WHERE"
				+ " {"
				+ " { [] foaf:name ?name1}"
				+ " UNION"
				+ " { [] vCard:FN ?name2}"
				+ " OPTIONAL { ?c  foaf:given   ?given ; foaf:family  ?family } "
				+ " }";
		Query q = QueryFactory.create(query, Syntax.syntaxARQ);

		ElementWalker.walk(q.getQueryPattern(), new ElementVisitorBase() {

			public void visit(ElementPathBlock el) {

				// when it's a block of triples, add in some triple
				ElementPathBlock elCopy = new ElementPathBlock();
				Iterator<TriplePath> triples = el.patternElts();
				int index = 0;
				int numAdded = 0;
				while (triples.hasNext()) {
					TriplePath t = triples.next();
					if (t.getSubject().equals("")) {
						// add triple here, something like:
						elCopy.addTriple(t);
						numAdded++;
					}
					System.out.println(t.getObject());
					index++;
					System.out.println(index);
					teste.addMap(t);
				}
				el = elCopy;
				System.out.println();
			}

			public void visit(ElementSubQuery el) {

				// get the subquery and walk it
				ElementGroup subQP = (ElementGroup) el.getQuery()
						.getQueryPattern();
				ElementWalker.walk(subQP, this);
				System.out.println("SubQuery");
			}

			public void visit(ElementOptional el) {

				// get optional elements and walk them
				Element optionalQP = el.getOptionalElement();
//				ElementWalker.walk(optionalQP, this);
				System.out.println("OPT");
				teste.addMap("OPT");
			}

			public void visit(ElementUnion el) {

				// for ( Element e : el.getElements() )
				teste.addMap("UNION");
				// ElementWalker.walk(e, this);
				System.out.println("UNION");
			}
		});
		System.out.println(map);

		teste.organizaVetor(map);
	}
}
